/*
 * @ : Copyright (c) 2021 Phytium Information Technology, Inc. 
 *  
 * SPDX-License-Identifier: Apache-2.0.
 * 
 * @Date: 2021-07-22 17:31:45
 * @LastEditTime: 2021-08-11 09:00:03
 * @Description:  This files is for 
 * 
 * @Modify History: 
 *  Ver   Who        Date         Changes
 * ----- ------     --------    --------------------------------------
 */
#include <string.h>
#include <stdio.h>
#include "kernel.h"
#include "ft_debug.h"
#include "generic_timer.h"
#include "parameters.h"
#include "qspi.h"
#include "qspi_hw.h"

static QSpiCtrl ctrl;

void NorFlashTestInit(QSpiCtrl *pCtrl, QSpiConfig *pConfig)
{
    u32 id = QSPI_INSTANCE;
    u32 ret = QSPI_SUCCESS;

    memset(pCtrl, 0, sizeof(QSpiCtrl));
    printf("start test\r\n");
    *pConfig = *NorFlashLookupConfig(id);
    ret = NorFlashInit(pCtrl, pConfig);
}

void NorFlashReadIDTest()
{
    QSpiCtrl *pCtrl = &ctrl;
    QSpiConfig *pConfig = &ctrl.config;
    u8 flashId[6] = {0};
    u32 ret = QSPI_SUCCESS;

    NorFlashTestInit(pCtrl, pConfig);

    ret = NorFlashReadReg(pCtrl, QSPI_FLASH_CMD_RDID, flashId, sizeof(flashId));

    if (QSPI_SUCCESS != ret)
    {
        printf("failed, test result 0x%x\r\n", ret);
    }

    printf("Manufacturer ID: 0x%x\r\n", flashId[0]);
    if ((0x02 == flashId[1]) && (0x19 == flashId[2]))
    {
        printf("Capcity: 256MB\r\n");
    }
    else if ((0x20 == flashId[1]) && (0x18 == flashId[2]))
    {
        printf("Capcity: 128MB\r\n");
    }
    else
    {
        printf("Capcity: Unkonwn\r\n");
    }

    if (0x00 == flashId[4])
    {
        printf("Sector: 256KB\r\n");
    }
    else if (0x01 == flashId[4])
    {
        printf("Sector: 64KB\r\n");
    }
    else
    {
        printf("Sector: Unkonwn\r\n");
    }

    printf("Family Id: 0x%x\r\n", flashId[5]);     
}

#define DAT_LENGTH  (256)
static u8 rdBuf[DAT_LENGTH + 1];
void NorFlashReadMemTest(boolean aligned)
{
    QSpiCtrl *pCtrl = &ctrl;
    QSpiConfig *pConfig = &ctrl.config;
    u32 ret = QSPI_SUCCESS;
    u32 flashAddr = aligned ? 0x0: 0x1;
    u64 timeStart, timeEnd;

    NorFlashTestInit(pCtrl, pConfig);
    timeStart = GenericTimerRead();
    ret = NorFlashRead(pCtrl, QSPI_FLASH_CMD_READ, flashAddr, rdBuf, DAT_LENGTH);
    timeEnd = GenericTimerRead();

    if (QSPI_SUCCESS != ret)
    {
        printf("failed to read mem, test result 0x%x\r\n", ret);
        return;
    }
    else
    {
        printf("read success, consumed time: 0x%x ms \r\n",
               (timeEnd - timeEnd) / (GenericTimerFrequecy() / NANO_TO_MICRO));
    }

    printf("read finished\r\n");
    FtDumpHexByte(rdBuf, DAT_LENGTH);
}


#define SR1NV_WIP_D       BIT(0)
#define SR1NV_WEL_D       BIT(1)
#define SR1NV_BP_NV       GENMASK(4, 2) 
#define SR1NV_E_ERR_D     BIT(5) 
#define SR1NV_P_ERR_D     BIT(6)
#define SR1NV_SRWD_NV     BIT(7)
void NorFlashReadSrTest()
{
    QSpiCtrl *pCtrl = &ctrl;
    QSpiConfig *pConfig = &ctrl.config;
    u32 ret = QSPI_SUCCESS;
    u8 sr1Nv = 0;

    NorFlashTestInit(pCtrl, pConfig);

    ret = NorFlashReadReg(pCtrl, QSPI_FLASH_CMD_RDSR1, &sr1Nv, sizeof(sr1Nv));
    if (QSPI_SUCCESS != ret)
    {
        printf("failed to read mem, test result 0x%x\r\n", ret);
        return;
    }

    printf("sr1 : 0x%x, wip: %d, blk protection: %x\r\n", 
                    sr1Nv,
                    (SR1NV_WIP_D & sr1Nv) ? 1 : 0,
                    (SR1NV_BP_NV & sr1Nv));

    ret = NorFlashWriteReg(pCtrl, QSPI_FLASH_CMD_WRDI, NULL, 0);
    ret |= NorFlashReadReg(pCtrl, QSPI_FLASH_CMD_RDSR1, &sr1Nv, sizeof(sr1Nv));
    if (QSPI_SUCCESS != ret)
    {
        printf("failed to read mem, test result 0x%x\r\n", ret);
        return;
    }

    printf("after disable write, sr1 : 0x%x, wip: %d, blk protection: %x\r\n", 
                    sr1Nv,
                    (SR1NV_WIP_D & sr1Nv) ? 1 : 0,
                    (SR1NV_BP_NV & sr1Nv));
}